package ru.vba.context.impl;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import ru.vba.context.FieldContext;
import ru.vba.context.GameContext;
import ru.vba.exceptions.GameException;
import ru.vba.exceptions.GameNotStartedException;
import ru.vba.pojo.Player;
import ru.vba.strategy.EndTurnNotifier;

public class EruditContext implements GameContext {
	private List<Player> players;
	private volatile Player currentPlayer;
	private FieldContext field;
	private Long timeout;
	private Long startTime;

	public EruditContext(List<Player> players, FieldContext context) {
		this.players = players;
		this.field = context;
	}

	private ScheduledExecutorService scheduledThreadPool = Executors
			.newScheduledThreadPool(1);

	public synchronized Player getCurrentPlayer() throws GameException {
		if (startTime == null){
			throw new GameNotStartedException();
		}
		return currentPlayer;
	}

	public List<Player> getPlayers() {
		return players;
	}

	public FieldContext getField() {
		return field;
	}

	public Long getTimeout() {
		return timeout;
	}

	public void setTimeout(Long timeout) {
		this.timeout = timeout;
	}

	public void charge() {
		//scheduledThreadPool.shutdown();
	}

	public void putError(Exception e) {
	}

	public synchronized void nextPlayer(final EndTurnNotifier notifier) throws GameException {
		if (startTime == null){
			throw new GameNotStartedException();
		}
		int index = players.indexOf(currentPlayer);
		if (index == players.size() - 1) {
			currentPlayer = players.get(0);
		} else {
			currentPlayer = players.get(index + 1);
		}

		scheduledThreadPool.schedule(new Runnable() {
			public void run() {
				try {
					notifier.endTurn();
				} catch (GameException e) {
				}
			}
		}, timeout, TimeUnit.SECONDS);
	}

	public Long getStartTime() {
		return startTime;
	}

	public void setStartTime(Long startTime) {
		this.startTime = startTime;
	}

	public void start() {
		startTime = System.currentTimeMillis();
	}

}
